package service

import (
	"errors"
	"fitness/go-admin/internal/model"
	"fitness/go-admin/internal/repository"
	"fitness/go-admin/pkg/errcode"

	"gorm.io/gorm"
)

type PermissionService interface {
	Create(req *model.PermissionCreateReq) error
	GetByID(id uint) (*model.Permission, error)
	List() ([]model.Permission, error)
	GetRolePermissions(roleID uint) ([]model.Permission, error)
	AssignPermissionsToRole(roleID uint, permissionIDs []uint) error
	RemovePermissionFromRole(roleID, permissionID uint) error
}

type permissionService struct {
	permissionRepo repository.PermissionRepository
	roleRepo       repository.RoleRepository
}

func NewPermissionService(permissionRepo repository.PermissionRepository, roleRepo repository.RoleRepository) PermissionService {
	return &permissionService{
		permissionRepo: permissionRepo,
		roleRepo:       roleRepo,
	}
}

// Create 创建权限
func (s *permissionService) Create(req *model.PermissionCreateReq) error {
	// 检查权限代码是否已存在
	existing, err := s.permissionRepo.GetByCode(req.Code)
	if err == nil && existing.ID > 0 {
		return errcode.NewError(errcode.PermissionExists)
	}

	permission := &model.Permission{
		Name:        req.Name,
		Code:        req.Code,
		Resource:    req.Resource,
		Action:      req.Action,
		Description: req.Description,
	}

	return s.permissionRepo.Create(permission)
}

// GetByID 获取权限详情
func (s *permissionService) GetByID(id uint) (*model.Permission, error) {
	permission, err := s.permissionRepo.GetByID(id)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errcode.NewError(errcode.PermissionNotFound)
		}
		return nil, err
	}
	return permission, nil
}

// List 获取权限列表
func (s *permissionService) List() ([]model.Permission, error) {
	return s.permissionRepo.List()
}

// GetRolePermissions 获取角色的权限列表
func (s *permissionService) GetRolePermissions(roleID uint) ([]model.Permission, error) {
	// 检查角色是否存在
	_, err := s.roleRepo.GetByID(roleID)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errcode.NewError(errcode.RoleNotFound)
		}
		return nil, err
	}

	return s.roleRepo.GetRolePermissions(roleID)
}

// AssignPermissionsToRole 为角色分配权限（批量）
func (s *permissionService) AssignPermissionsToRole(roleID uint, permissionIDs []uint) error {
	// 检查角色是否存在
	role, err := s.roleRepo.GetByID(roleID)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errcode.NewError(errcode.RoleNotFound)
		}
		return err
	}

	// 检查角色是否被禁用
	if role.Status != 1 {
		return errcode.NewError(errcode.RoleDisabled)
	}

	// 检查所有权限是否存在
	for _, permID := range permissionIDs {
		_, err := s.permissionRepo.GetByID(permID)
		if err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return errcode.NewError(errcode.PermissionNotFound)
			}
			return err
		}
	}

	// 批量分配权限
	for _, permID := range permissionIDs {
		// 忽略已存在的关联
		_ = s.roleRepo.AssignPermission(roleID, permID)
	}

	return nil
}

// RemovePermissionFromRole 移除角色权限
func (s *permissionService) RemovePermissionFromRole(roleID, permissionID uint) error {
	// 检查角色是否存在
	_, err := s.roleRepo.GetByID(roleID)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errcode.NewError(errcode.RoleNotFound)
		}
		return err
	}

	// 检查权限是否存在
	_, err = s.permissionRepo.GetByID(permissionID)
	if err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errcode.NewError(errcode.PermissionNotFound)
		}
		return err
	}

	return s.roleRepo.RemovePermission(roleID, permissionID)
}
